package com.sx.widget.log;

import android.util.Log;

import androidx.annotation.Nullable;
import androidx.lifecycle.MutableLiveData;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @Author YY
 * @Date 2021/4/6
 * @Description 日志封装
 */
public class LogUtils {
    static boolean isDebug = true;
    //类名
    static String className;
    //方法名
    static String methodName;
    //行数
    static int lineNumber;

    public static void setIsDebug(boolean debug) {
        isDebug = debug;
    }

    public static MutableLiveListData<LogBean> logE = new MutableLiveListData<LogBean>();
    public static MutableLiveListData<LogBean> logD = new MutableLiveListData<LogBean>();
    public static MutableLiveListData<LogBean> logI = new MutableLiveListData<LogBean>();
    public static MutableLiveListData<LogBean> logV = new MutableLiveListData<LogBean>();
    public static MutableLiveListData<LogBean> logW = new MutableLiveListData<LogBean>();

    /**
     * 判断是否可以调试
     *
     * @return
     */
    public static boolean isDebug() {
        return isDebug;
    }

    private static String createLog(String log) {
        StringBuffer buffer = new StringBuffer();
        buffer.append("================");
        buffer.append(methodName);
        buffer.append("(").append(className).append(":").append(lineNumber).append(") ================:");
        buffer.append(log);
        return buffer.toString();
    }

    /**
     * 获取文件名、方法名、所在行数
     *
     * @param sElements
     */
    private static void getMethodNames(StackTraceElement[] sElements) {
        className = sElements[1].getFileName();
        methodName = sElements[1].getMethodName();
        lineNumber = sElements[1].getLineNumber();
    }

    public static void e(String message) {
        if (!isDebug()) {
            return;
        }
        getMethodNames(new Throwable().getStackTrace());
        String log = createLog(message);
        Log.e(className, log);
        logE.addData(new LogBean(5,log));

    }

    public static void i(String message) {
        if (!isDebug()) {
            return;
        }
        getMethodNames(new Throwable().getStackTrace());
        String log = createLog(message);
        Log.i(className, log);
        logI.addData(new LogBean(3,log));
    }

    public static void d(String message) {
        if (!isDebug()) {
            return;
        }
        getMethodNames(new Throwable().getStackTrace());
        String log = createLog(message);
        Log.d(className, log);
        logD.addData(new LogBean(2,log));
    }

    public static void v(String message) {
        if (!isDebug()) {
            return;
        }
        getMethodNames(new Throwable().getStackTrace());
        String log = createLog(message);
        Log.v(className, log);
        logV.addData(new LogBean(1,log));
    }

    public static void w(String message) {
        if (!isDebug()) {
            return;
        }
        getMethodNames(new Throwable().getStackTrace());
        String log = createLog(message);
        Log.w(className, createLog(message));
        logW.addData(new LogBean(4,log));
    }



    public static class MutableLiveListData<T> extends MutableLiveData<List<T>> {

        public  class Builder<T> {
            public MutableLiveListData<T> mutableLiveListData;

            public Builder(MutableLiveListData<T> mutableLiveListData) {
                this.mutableLiveListData = mutableLiveListData;
            }

            public List<T> entity;

            public Builder add(T data) {
                if (entity == null) {
                    entity = new ArrayList<T>();
                }
                entity.add(data);
                return this;
            }

            public void buildPost() {
                mutableLiveListData.postValue(entity);
            }

            public void buildSet() {
                mutableLiveListData.setValue(entity);
            }
            public void buildAdd() {
                mutableLiveListData.addData(entity);
            }
        }

        public void addData(T data) {
            List<T> value = this.getValue();
            if (value == null) {
                value = new ArrayList<T>();
            }
            value.add(data);
            this.setValue(value);
        }

        public void addData(List<T> list) {
            if (list != null && list.size() > 0) {
                List<T> value = getValue();
                value.addAll(list);
                setValue(value);
            }
        }

        public void addData(T... data) {
            List<T> value = this.getValue();
            if (value == null) {
                value = new ArrayList<T>();
            }
            for (T datum : data) {
                value.add(datum);
            }
            this.setValue(value);
        }

        public void setData(int index, T data) {
            List<T> value = this.getValue();
            if (value != null) {
                value.set(index, data);
                this.setValue(value);
            }
        }

        public T getData(T data) {
            List<T> value = this.getValue();
            if (value != null) {
                return value.get(value.indexOf(data));
            }
            return null;
        }

        public void indexOf(T data) {
            List<T> value = this.getValue();
            if (value != null) {
                if (value.contains(data)) {
                    value.set(value.indexOf(data), data);
                } else {
                    addData(data);
                }
            } else {
                addData(data);
            }
            this.setValue(value);
        }

        public void deleteList(T data) {
            if (data != null) {
                List<T> value = this.getValue();
                if (value != null) {
                    value.remove(data);
                    this.setValue(value);
                }
            }
        }

        public void clean() {
            List<T> value = this.getValue();
            if (value != null) {
                value.clear();
                this.setValue(value);
            }
        }


        @Nullable
        @Override
        public List<T> getValue() {
            List<T> value = super.getValue();
            if (value == null) {
                value = new ArrayList<>();
            }
            return value;
        }

        public void callValue(){
            postValue(getValue());
        }


    }
}
